《算法之美》第一二章读书笔记

第一章:

1.分治法和动态规划(dp)的区别:

1)分治法(自顶向下):

主要用递归操作,并且各个部分之间没有联系。需要递归若干次并且需要重复计算已经计算好的数据。因此效率低

function Devide(x){
 if(足够小并且简单)
{
return x;
}
else{
for (int i=0;i<n;i++)
{
devide(xi);//进行递归
}
}
}

主要应用:

传染病问题,二分搜索,快速排序,矩阵乘法,汉诺塔问题


2)动态规划(自底向上)

主要通过之前已知的数据,推导出另一部分的数据,各个数据之间联系很大。

不需要重复计算已知的值,但是有的时候会计算出后期完全没有用到的数据,效率高于分治法。


主要应用:

快速傅里叶;多边形最优分割;找零钱问题;最短路径问题;背包问题;链式乘法问题


第二章:指针与数组

1.指针与自增

*p++  <==> *(p++),因为++和*是同一优先级,因此按照从右到左的结合顺序;该语句表示:获取当前p指针的值,然后将指针后移

(*p)++,表示读取p指针当中的内容,然后自增1

*++p和*(++p)是一样的,都是指针后移1位之后,读取p指针的指向的后一个数据;


2.z字形问题:

// ch2-2.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
/*
Z字形编排问题
*/
#include<iostream>
#include<iomanip>//用来格式化输出结果
using namespace std;

#define SIZE 8

int _tmain(int argc, _TCHAR* argv[])
{
	int matrix[SIZE][SIZE] = {0};
	int a[SIZE][SIZE] = {0};
	int *p = &matrix[0][0];



	for (int i = 0; i < SIZE*SIZE; i++)
	{
		*p++ = i;
	
	}
	cout << "原始矩阵----------------------------\n";
	//原始矩阵是从0~63的8*8的矩阵
	for (int i = 0; i < SIZE; i++)
	{
		for (int j = 0; j < SIZE; j++)
		{
			cout << setw(4) << *(*(matrix+i)+j);
		
		}
		cout << endl;
	}

	int i = 0, j = 0;

	for (int x = 0; x < SIZE; x++)
	{
		for (int y = 0; y < SIZE; y++)
		{
			*(*(a + i) + j) = *(*(matrix + x) + y);//将matrix的内容按照某一个特定的顺序复制到a矩阵当中。
			//case1:如果在第0行或者是第size-1行,并且是偶数列的时候,向右移动
			if ((i == 0 || i == SIZE - 1 )&& j % 2 == 0)
			{
				j++;
				continue;
			
			}
			//case2:如果在第0列或者第size-1列,并且是奇数行的时候,向下移动
			if ((j == 0 || j == SIZE - 1) && i % 2 == 1)
			{
				i++;
				continue;
			
			}
			//case3:如果(i+j)%2是偶数,那么就向右上移动
			if ((i + j) % 2 == 0)
			{
				i--;
				j++;
				continue;
			
			}
			//case4:如果(i+j)%2是奇数,那么就向左下移动
			else if ((i + j) % 2 == 1)
			{
				i++;
				j--;
				continue;
			
			}
		
		}
	
	}

	cout << "经过Z字形转变之后\n";
	for (int i = 0; i < SIZE; i++)
	{
		for (int j = 0; j < SIZE; j++)
		{
			cout << setw(4) << *(*(a + i) + j);
		
		}
		cout << endl;
	
	}



	return 0;
}


2.3大数乘法问题:

大数问题的集合:http://blog.csdn.net/lisp1995/article/category/6384570

输入数据:从右往左输入数据:

若想输入12345,那么a[0]=5,a[1]=4,a[2]=3,a[3]=2,a[4]=1

// ch2-3.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

/*
大数乘法:输入是从右向左输入的,eg:
若想输入12345,那么a[0]=5,a[1]=4,a[2]=3,a[3]=2,a[4]=1

*/
#include<iostream>
#include<memory.h>
using namespace std;
#define SIZE 3
int* multi(int size1, int *num1, int size2, int *num2)
{
	int size = size1 + size2;
	int *result = new int[size];
	
	
	memset(result, 0, sizeof(int)*size);

	for (int i=0; i < size1; i++)
	{
		int k = i;
		for (int j = 0; j < size2; j++)
		{
			result[k++] += num1[j] * num2[i];
		
		}
	
	}
	//对于计算结果进行修改,将大于10的进行取模进位
	for (int i = 0; i < size; i++)
	{
		if (result[i]>10)
		{
		
			result[i + 1] += result[i] / 10;//进位
			result[i] %= 10;//保留当前位的个位
		}
	
	}
	return result;
}



int _tmain(int argc, _TCHAR* argv[])
{
	int num1[SIZE] = { 2, 2 };

	int num2[SIZE] = { 1, 2 };

	//cout << length(num1) << endl;
	//cout << length(num2) << endl;
	int *result = multi(3, num1, 3, num2);
	//输出22*21的结果,从右往左进行计算,num1[0]是个位
	for (int i = 3 * 2 - 1; i >= 0; i--)
	{
	
		cout << result[i];
	}
	delete[] result;
	return 0;
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构与算法是计算机科学的基础和核心领域之一,第ba介绍了数据结构的相关内容。 本主要包括以下几个方面的内容: 1. 线性结构:线性结构是指数据元素之间存在一对一的关系,包括线性表、栈和队列。线性表是最基本的数据结构之一,它分为顺序表和链表两种形式。顺序表使用数组实现,插入和删除操作相对低效。链表使用指针实现,插入和删除操作较为灵活。 2. 树结构:树结构是一种层次结构,由节点和边组成。常见的树结构有二叉树、二叉搜索树和平衡二叉树等。二叉树中每个节点最多有两个子节点,二叉搜索树中左子节点的值小于根节点,右子节点的值大于根节点,查找效率较高。平衡二叉树是一种保持左右子树高度差不大于1的二叉搜索树。 3. 图结构:图结构是由节点和边组成的非线性结构。图分为有向图和无向图。图的表示方法有邻接矩阵和邻接表两种。深度优先搜索和广度优先搜索是图的常用遍历方法,可用于寻找路径、连通分量等问题。 4. 排序算法:排序算法是对一组无序数据进行按照某个规则进行有序排列的算法。第ba介绍了常见的排序算法,包括冒泡排序、插入排序、选择排序、归并排序、快速排序等。每种排序算法的时间复杂度和空间复杂度不同,选择合适的排序算法可以提高性能。 5. 查找算法:查找算法是在一组数据中搜索某个特定元素的算法。第ba介绍了顺序查找、二分查找和哈希查找等常见的查找算法。二分查找是在有序数组中应用最广泛的查找算法,通过不断缩小查找范围来快速定位目标值。 通过学习这些内容,我们可以了解不同数据结构的特点和应用场景,以及常见的排序和查找算法。掌握好这些知识,对于解决实际问题和提高程序效率都有很大帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值